{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/meta-llama/llama-stack/blob/main/docs/notebooks/llamastack_agents_getting_started_examples.ipynb)\n",
    "\n",
    "# Llama Stack Agents - Getting Started Guide\n",
    "\n",
    "This notebook provides a comprehensive introduction to building AI agents with Llama Stack. The Agent SDK is built on top of an open source version of **OpenAI's Responses+ APIs**, providing a standardized interface for agent workflows.\n",
    "\n",
    "## What You'll Learn\n",
    "\n",
    "1. **Basic Agent Creation** - Simple Q&A agents with streaming\n",
    "2. **Multi-Turn Conversations** - Maintaining context across conversations\n",
    "3. **RAG Integration** - Adding knowledge bases to your agents  \n",
    "4. **MCP Tools** - Extending agents with Model Context Protocol tools\n",
    "\n",
    "## Prerequisites\n",
    "\n",
    "- Llama Stack server running: `llama stack run starter --port 8321`\n",
    "- A model provider configured (Ollama, Fireworks, etc.)\n",
    "- Python 3.10+\n",
    "\n",
    "## Setup"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Client initialized successfully!\n",
      "   Base URL: http://localhost:8321\n"
     ]
    }
   ],
   "source": [
    "# Import required libraries\n",
    "import json\n",
    "from typing import Any, Dict\n",
    "\n",
    "from llama_stack_client import LlamaStackClient, Agent\n",
    "from llama_stack_client.types import UserMessage\n",
    "\n",
    "# Initialize client\n",
    "client = LlamaStackClient(base_url=\"http://localhost:8321\")\n",
    "\n",
    "print(\"✅ Client initialized successfully!\")\n",
    "print(f\"   Base URL: http://localhost:8321\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Created agent successfully\n"
     ]
    }
   ],
   "source": [
    "# Create a basic agent using the Agent class\n",
    "agent = Agent(\n",
    "    client=client,\n",
    "    model=\"ollama/llama3.3:70b\",\n",
    "    instructions=\"You are a helpful AI assistant that can answer questions and help with tasks.\",\n",
    ")\n",
    "\n",
    "print(\"✅ Created agent successfully\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "# Part 1: Basic Agent Example\n",
    "\n",
    "Let's start with a simple agent that can answer questions. This demonstrates:\n",
    "- Agent creation with basic configuration\n",
    "- Session management\n",
    "- Streaming responses"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/conversations \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Created session: conv_e6afd7aaa97b49ce8f4f96a801b07893d9cb784d72e53e3c\n"
     ]
    }
   ],
   "source": [
    "# Create agent session\n",
    "basic_session_id = agent.create_session(session_name=\"basic_example_session\")\n",
    "\n",
    "print(f\"✅ Created session: {basic_session_id}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/responses \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "User: What is the capital of France? Please explain briefly.\n",
      "\n",
      "Assistant: The capital of France is Paris. It's the country's largest city, known for iconic landmarks like the Eiffel Tower, Notre-Dame Cathedral, and the Louvre Museum, serving as the center of French politics, culture, and economy.The capital of France is Paris. It's the country's largest city, known for iconic landmarks like the Eiffel Tower, Notre-Dame Cathedral, and the Louvre Museum, serving as the center of French politics, culture, and economy.\n",
      "\n",
      "✅ Response captured: 223 characters\n"
     ]
    }
   ],
   "source": [
    "# Send a message to the agent with streaming\n",
    "query = \"What is the capital of France? Please explain briefly.\"\n",
    "\n",
    "print(f\"User: {query}\\n\")\n",
    "print(\"Assistant: \", end='')\n",
    "\n",
    "# Create a turn with streaming\n",
    "response = agent.create_turn(\n",
    "    session_id=basic_session_id,\n",
    "    messages=[UserMessage(content=query, role=\"user\")],\n",
    "    stream=True,\n",
    ")\n",
    "\n",
    "# Stream the response\n",
    "output_text = \"\"\n",
    "for chunk in response:\n",
    "    if chunk.event.event_type == \"turn_completed\":\n",
    "        output_text = chunk.event.final_text\n",
    "        print(output_text)\n",
    "        break\n",
    "    elif chunk.event.event_type == \"step_progress\":\n",
    "        # Print text deltas as they arrive\n",
    "        if hasattr(chunk.event.delta, 'text'):\n",
    "            print(chunk.event.delta.text, end='', flush=True)\n",
    "\n",
    "print(f\"\\n✅ Response captured: {len(output_text)} characters\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: DELETE http://localhost:8321/v1/conversations/conv_e6afd7aaa97b49ce8f4f96a801b07893d9cb784d72e53e3c \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Session cleaned up\n"
     ]
    }
   ],
   "source": [
    "# Clean up the session\n",
    "client.conversations.delete(conversation_id=basic_session_id)\n",
    "print(\"✅ Session cleaned up\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "# Part 2: Advanced Agent Features\n",
    "\n",
    "Now let's explore more advanced capabilities:\n",
    "- Multi-turn conversations with context memory\n",
    "- RAG (Retrieval-Augmented Generation) patterns"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.1 Multi-Turn Conversation\n",
    "\n",
    "Demonstrate how agents can maintain context across multiple conversation turns."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/conversations \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Created conversation agent\n",
      "✅ Created session: conv_936121c2e27b7d1f7d3f0b6a62adce867d79268f5f9ce265\n"
     ]
    }
   ],
   "source": [
    "# Create agent for multi-turn conversation\n",
    "conv_agent = Agent(\n",
    "    client=client,\n",
    "    model=\"ollama/llama3.3:70b\",\n",
    "    instructions=\"You are a helpful assistant that remembers context from previous messages.\",\n",
    ")\n",
    "\n",
    "print(\"✅ Created conversation agent\")\n",
    "\n",
    "conv_session_id = conv_agent.create_session(session_name=\"multi_turn_session\")\n",
    "print(f\"✅ Created session: {conv_session_id}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/responses \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "============================================================\n",
      "Turn 1\n",
      "============================================================\n",
      "User: My name is Alice and I'm learning about AI.\n",
      "Assistant: Nice to meet you, Alice! It's great that you're interested in learning about AI. What aspects of AI would you like to explore? Are you curious about machine learning, natural language processing, or something else? I'll be happy to help and provide information tailored to your interests.Nice to meet you, Alice! It's great that you're interested in learning about AI. What aspects of AI would you like to explore? Are you curious about machine learning, natural language processing, or something else? I'll be happy to help and provide information tailored to your interests.\n",
      "\n",
      "============================================================\n",
      "Turn 2\n",
      "============================================================\n",
      "User: What are some good resources for beginners?\n",
      "Assistant: "
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/responses \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "As a beginner, it's essential to start with resources that provide a solid foundation in AI concepts. Here are some recommendations:\n",
      "\n",
      "1. **Online Courses**:\n",
      "\t* Andrew Ng's Machine Learning course on Coursera: A popular and comprehensive introduction to machine learning.\n",
      "\t* Stanford University's Natural Language Processing with Deep Learning Specialization on Coursera: Covers NLP fundamentals and deep learning techniques.\n",
      "2. **Books**:\n",
      "\t* \"Introduction to Artificial Intelligence\" by Philip C. Jackson Jr.: A gentle introduction to AI concepts, including machine learning and computer vision.\n",
      "\t* \"Deep Learning\" by Ian Goodfellow, Yoshua Bengio, and Aaron Courville: A detailed book on deep learning techniques, although it may require some prior knowledge of linear algebra and calculus.\n",
      "3. **Websites and Blogs**:\n",
      "\t* Machine Learning Mastery: A website offering tutorials, examples, and explanations on various machine learning topics.\n",
      "\t* KDnuggets: A popular blog covering AI, machine learning, and data science news, tutorials, and research papers.\n",
      "4. **YouTube Channels**:\n",
      "\t* 3Blue1Brown (Grant Sanderson): Engaging video explanations on AI, machine learning, and linear algebra concepts.\n",
      "\t* Sentdex: Offers video tutorials on various AI topics, including machine learning, deep learning, and computer vision.\n",
      "5. **Communities and Forums**:\n",
      "\t* Kaggle: A platform for data science competitions and hosting datasets, where you can learn from others and participate in discussions.\n",
      "\t* Reddit's r/MachineLearning and r/AI: Active communities discussing AI-related topics, sharing resources, and providing feedback on projects.\n",
      "\n",
      "Remember, learning about AI is a continuous process. Start with the basics, build projects, and gradually move on to more advanced topics. Practice and experimentation are key to gaining hands-on experience.\n",
      "\n",
      "What specific area of AI would you like to explore first, Alice?As a beginner, it's essential to start with resources that provide a solid foundation in AI concepts. Here are some recommendations:\n",
      "\n",
      "1. **Online Courses**:\n",
      "\t* Andrew Ng's Machine Learning course on Coursera: A popular and comprehensive introduction to machine learning.\n",
      "\t* Stanford University's Natural Language Processing with Deep Learning Specialization on Coursera: Covers NLP fundamentals and deep learning techniques.\n",
      "2. **Books**:\n",
      "\t* \"Introduction to Artificial Intelligence\" by Philip C. Jackson Jr.: A gentle introduction to AI concepts, including machine learning and computer vision.\n",
      "\t* \"Deep Learning\" by Ian Goodfellow, Yoshua Bengio, and Aaron Courville: A detailed book on deep learning techniques, although it may require some prior knowledge of linear algebra and calculus.\n",
      "3. **Websites and Blogs**:\n",
      "\t* Machine Learning Mastery: A website offering tutorials, examples, and explanations on various machine learning topics.\n",
      "\t* KDnuggets: A popular blog covering AI, machine learning, and data science news, tutorials, and research papers.\n",
      "4. **YouTube Channels**:\n",
      "\t* 3Blue1Brown (Grant Sanderson): Engaging video explanations on AI, machine learning, and linear algebra concepts.\n",
      "\t* Sentdex: Offers video tutorials on various AI topics, including machine learning, deep learning, and computer vision.\n",
      "5. **Communities and Forums**:\n",
      "\t* Kaggle: A platform for data science competitions and hosting datasets, where you can learn from others and participate in discussions.\n",
      "\t* Reddit's r/MachineLearning and r/AI: Active communities discussing AI-related topics, sharing resources, and providing feedback on projects.\n",
      "\n",
      "Remember, learning about AI is a continuous process. Start with the basics, build projects, and gradually move on to more advanced topics. Practice and experimentation are key to gaining hands-on experience.\n",
      "\n",
      "What specific area of AI would you like to explore first, Alice?\n",
      "\n",
      "============================================================\n",
      "Turn 3\n",
      "============================================================\n",
      "User: Can you remind me what my name is?\n",
      "Assistant: "
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/responses \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your name is Alice! I remember that from our previous conversation when you introduced yourself as someone interested in learning about AI. How can I assist you further today?Your name is Alice! I remember that from our previous conversation when you introduced yourself as someone interested in learning about AI. How can I assist you further today?\n",
      "\n",
      "✅ Completed 3 conversational turns with context retention\n"
     ]
    }
   ],
   "source": [
    "# Conversation turns that build on each other\n",
    "conversation_turns = [\n",
    "    \"My name is Alice and I'm learning about AI.\",\n",
    "    \"What are some good resources for beginners?\",\n",
    "    \"Can you remind me what my name is?\",\n",
    "]\n",
    "\n",
    "for i, query in enumerate(conversation_turns, 1):\n",
    "    print(f\"\\n{'='*60}\")\n",
    "    print(f\"Turn {i}\")\n",
    "    print(f\"{'='*60}\")\n",
    "    print(f\"User: {query}\")\n",
    "\n",
    "    response = conv_agent.create_turn(\n",
    "        session_id=conv_session_id,\n",
    "        messages=[UserMessage(content=query, role=\"user\")],\n",
    "        stream=True,\n",
    "    )\n",
    "\n",
    "    print(\"Assistant: \", end='')\n",
    "    for chunk in response:\n",
    "        if chunk.event.event_type == \"turn_completed\":\n",
    "            output = chunk.event.final_text\n",
    "            print(output)\n",
    "            break\n",
    "        elif chunk.event.event_type == \"step_progress\":\n",
    "            if hasattr(chunk.event.delta, 'text'):\n",
    "                print(chunk.event.delta.text, end='', flush=True)\n",
    "\n",
    "print(f\"\\n✅ Completed {len(conversation_turns)} conversational turns with context retention\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: DELETE http://localhost:8321/v1/conversations/conv_936121c2e27b7d1f7d3f0b6a62adce867d79268f5f9ce265 \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Session cleaned up\n"
     ]
    }
   ],
   "source": [
    "# Cleanup\n",
    "client.conversations.delete(conversation_id=conv_session_id)\n",
    "print(\"✅ Session cleaned up\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2.2 RAG (Retrieval-Augmented Generation) Pattern\n",
    "\n",
    "Demonstrate how to provide context to the agent for more accurate responses."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Knowledge base: 3 Paul Graham essay excerpts\n",
      "  - pg_essay_1: What I Worked On\n",
      "  - pg_essay_2: How to Start a Startup\n",
      "  - pg_essay_3: Maker's Schedule, Manager's Schedule\n"
     ]
    }
   ],
   "source": [
    "# Sample knowledge base: Paul Graham essay excerpts\n",
    "# This is a common RAG example - using actual content from Paul Graham's essays\n",
    "documents = [\n",
    "    {\n",
    "        \"doc_id\": \"pg_essay_1\",\n",
    "        \"content\": \"\"\"What I Worked On\n",
    "\n",
    "        Before college the two main things I worked on, outside of school, were writing and programming.\n",
    "        I didn't write essays. I wrote what beginning writers were supposed to write then, and probably\n",
    "        still are: short stories. My stories were awful. They had hardly any plot, just characters with\n",
    "        strong feelings, which I imagined made them deep.\n",
    "\n",
    "        The first programs I tried writing were on the IBM 1401 that our school district used for what\n",
    "        was then called 'data processing.' This was in 9th grade, so I was 13 or 14. The school district's\n",
    "        1401 happened to be in the basement of our junior high school, and my friend Rich Draves and I got\n",
    "        permission to use it.\"\"\",\n",
    "        \"metadata\": {\"essay\": \"What I Worked On\", \"author\": \"Paul Graham\", \"year\": 2021}\n",
    "    },\n",
    "    {\n",
    "        \"doc_id\": \"pg_essay_2\",\n",
    "        \"content\": \"\"\"How to Start a Startup\n",
    "\n",
    "        You need three things to create a successful startup: to start with good people, to make something\n",
    "        customers actually want, and to spend as little money as possible. Most startups that fail do it\n",
    "        because they fail at one of these. A startup that does all three will probably succeed.\n",
    "\n",
    "        And that's kind of exciting, when you think about it, because all three are doable. Hard, but doable.\n",
    "        And since a startup that succeeds ordinarily makes its founders rich, that implies getting rich is\n",
    "        doable too. Hard, but doable.\"\"\",\n",
    "        \"metadata\": {\"essay\": \"How to Start a Startup\", \"author\": \"Paul Graham\", \"year\": 2005}\n",
    "    },\n",
    "    {\n",
    "        \"doc_id\": \"pg_essay_3\",\n",
    "        \"content\": \"\"\"Maker's Schedule, Manager's Schedule\n",
    "\n",
    "        One reason programmers dislike meetings so much is that they're on a different type of schedule\n",
    "        from other people. Meetings cost them more.\n",
    "\n",
    "        There are two types of schedule, which I'll call the manager's schedule and the maker's schedule.\n",
    "        The manager's schedule is for bosses. It's embodied in the traditional appointment book, with each\n",
    "        day cut into one hour intervals. When you use time that way, it's merely a practical problem to\n",
    "        meet with someone. But there's another way of using time that's common among people who make things,\n",
    "        like programmers and writers. They generally prefer to use time in units of half a day at least.\"\"\",\n",
    "        \"metadata\": {\"essay\": \"Maker's Schedule, Manager's Schedule\", \"author\": \"Paul Graham\", \"year\": 2009}\n",
    "    },\n",
    "]\n",
    "\n",
    "print(f\"Knowledge base: {len(documents)} Paul Graham essay excerpts\")\n",
    "for doc in documents:\n",
    "    print(f\"  - {doc['doc_id']}: {doc['metadata']['essay']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Created RAG agent\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/conversations \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Created session: conv_9ae94374c781501f2d712620dcc8e55961b5a226df229b1d\n"
     ]
    }
   ],
   "source": [
    "# Create RAG-enabled agent\n",
    "rag_agent = Agent(\n",
    "    client=client,\n",
    "    model=\"ollama/llama3.3:70b\",\n",
    "    instructions=(\n",
    "        \"You are a helpful AI assistant with access to a knowledge base. \"\n",
    "        \"When answering questions, use the provided context from the knowledge base. \"\n",
    "        \"If the context doesn't contain relevant information, say so.\"\n",
    "    ),\n",
    ")\n",
    "\n",
    "print(\"✅ Created RAG agent\")\n",
    "\n",
    "rag_session_id = rag_agent.create_session(session_name=\"rag_session\")\n",
    "print(f\"✅ Created session: {rag_session_id}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/responses \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Query: What did Paul Graham work on before college?\n",
      "Retrieved 1 relevant document(s)\n",
      "\n",
      "Answer: Based on the provided context from \"What I Worked On\", before college, Paul Graham worked on two main things outside of school: \n",
      "\n",
      "1. Writing (specifically short stories)\n",
      "2. Programming (initially on the IBM 1401)Based on the provided context from \"What I Worked On\", before college, Paul Graham worked on two main things outside of school: \n",
      "\n",
      "1. Writing (specifically short stories)\n",
      "2. Programming (initially on the IBM 1401)\n",
      "\n",
      "\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: DELETE http://localhost:8321/v1/conversations/conv_9ae94374c781501f2d712620dcc8e55961b5a226df229b1d \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Session cleaned up\n"
     ]
    }
   ],
   "source": [
    "# Query with context from Paul Graham essays\n",
    "query = \"What did Paul Graham work on before college?\"\n",
    "\n",
    "# Simulate retrieval (in production, use vector search)\n",
    "relevant_docs = [doc for doc in documents if \"before college\" in doc[\"content\"].lower()]\n",
    "context = \"\\n\\n\".join([f\"From '{doc['metadata']['essay']}':\\n{doc['content']}\"\n",
    "                       for doc in relevant_docs])\n",
    "\n",
    "# Create prompt with retrieved context\n",
    "prompt_with_context = f\"\"\"Context from knowledge base:\n",
    "{context}\n",
    "\n",
    "Question: {query}\n",
    "\n",
    "Please answer based on the provided context.\"\"\"\n",
    "\n",
    "print(f\"Query: {query}\")\n",
    "print(f\"Retrieved {len(relevant_docs)} relevant document(s)\\n\")\n",
    "print(\"Answer: \", end='')\n",
    "\n",
    "response = rag_agent.create_turn(\n",
    "    session_id=rag_session_id,\n",
    "    messages=[UserMessage(content=prompt_with_context, role=\"user\")],\n",
    "    stream=True,\n",
    ")\n",
    "\n",
    "for chunk in response:\n",
    "    if chunk.event.event_type == \"turn_completed\":\n",
    "        output = chunk.event.final_text\n",
    "        print(output)\n",
    "        break\n",
    "    elif chunk.event.event_type == \"step_progress\":\n",
    "        if hasattr(chunk.event.delta, 'text'):\n",
    "            print(chunk.event.delta.text, end='', flush=True)\n",
    "\n",
    "print(\"\\n\")\n",
    "client.conversations.delete(conversation_id=rag_session_id)\n",
    "print(\"✅ Session cleaned up\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "# Part 3: MCP (Model Context Protocol) Tools\n",
    "\n",
    "MCP provides a standardized way for AI models to interact with external tools and data sources.\n",
    "\n",
    "We'll demonstrate:\n",
    "- Defining MCP-compatible tools\n",
    "- Agent tool selection\n",
    "- Tool execution and response handling"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created 3 MCP tools:\n",
      "  - get_weather: Get current weather information for a specified location\n",
      "  - execute_code: Execute Python code and return the result\n",
      "  - web_search: Search the web for information\n"
     ]
    }
   ],
   "source": [
    "def create_mcp_tools():\n",
    "    \"\"\"Create MCP-compatible tool definitions.\"\"\"\n",
    "    return [\n",
    "        {\n",
    "            \"tool_name\": \"get_weather\",\n",
    "            \"description\": \"Get current weather information for a specified location\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"location\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"City and state/country, e.g., 'San Francisco, CA'\"\n",
    "                    },\n",
    "                    \"unit\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"enum\": [\"celsius\", \"fahrenheit\"],\n",
    "                        \"description\": \"Temperature unit\",\n",
    "                        \"default\": \"fahrenheit\"\n",
    "                    }\n",
    "                },\n",
    "                \"required\": [\"location\"]\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            \"tool_name\": \"execute_code\",\n",
    "            \"description\": \"Execute Python code and return the result\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"code\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"Python code to execute\"\n",
    "                    }\n",
    "                },\n",
    "                \"required\": [\"code\"]\n",
    "            }\n",
    "        },\n",
    "        {\n",
    "            \"tool_name\": \"web_search\",\n",
    "            \"description\": \"Search the web for information\",\n",
    "            \"parameters\": {\n",
    "                \"type\": \"object\",\n",
    "                \"properties\": {\n",
    "                    \"query\": {\n",
    "                        \"type\": \"string\",\n",
    "                        \"description\": \"Search query\"\n",
    "                    }\n",
    "                },\n",
    "                \"required\": [\"query\"]\n",
    "            }\n",
    "        },\n",
    "    ]\n",
    "\n",
    "tools = create_mcp_tools()\n",
    "print(f\"Created {len(tools)} MCP tools:\")\n",
    "for tool in tools:\n",
    "    print(f\"  - {tool['tool_name']}: {tool['description']}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "MCP tool configuration ready\n",
      "   Server: http://localhost:3000/sse\n",
      "   Format: MCP server-based\n",
      "\n",
      " To use MCP tools:\n",
      "   1. Set up your MCP server\n",
      "   2. Update MCP_SERVER_URL and MCP_ACCESS_TOKEN above\n",
      "   3. Pass mcp_tools to Agent(tools=mcp_tools)\n"
     ]
    }
   ],
   "source": [
    "# Example 2: MCP Server Configuration (0.3.0 format)\n",
    "\n",
    "# MCP server configuration\n",
    "# Replace with your actual MCP server URL and credentials\n",
    "MCP_SERVER_URL = \"https://api.example.com/mcp\"  # Your MCP server endpoint\n",
    "MCP_ACCESS_TOKEN = \"your-token-here\"  # Your authentication token\n",
    "\n",
    "MCP_ACCESS_TOKEN = \"YOUR_ACCESS_TOKEN_HERE\"\n",
    "## ran an MCP server locally, you can replace this field with your mcp server url\n",
    "MCP_SERVER_URL = \"http://localhost:3000/sse\"\n",
    "#MCP_SERVER_URL  = \"https://mcp.deepwiki.com/sse\"\n",
    "mcp_tools = [\n",
    "    {\n",
    "        \"type\": \"mcp\",\n",
    "        \"server_url\": MCP_SERVER_URL,\n",
    "        \"server_label\": \"weather\",\n",
    "        \"headers\": {\n",
    "            \"Authorization\": f\"Bearer {MCP_ACCESS_TOKEN}\",\n",
    "        },\n",
    "    }\n",
    "]\n",
    "\n",
    "\n",
    "print(\"MCP tool configuration ready\")\n",
    "print(f\"   Server: {MCP_SERVER_URL}\")\n",
    "print(\"   Format: MCP server-based\")\n",
    "print(\"\\n To use MCP tools:\")\n",
    "print(\"   1. Set up your MCP server\")\n",
    "print(\"   2. Update MCP_SERVER_URL and MCP_ACCESS_TOKEN above\")\n",
    "print(\"   3. Pass mcp_tools to Agent(tools=mcp_tools)\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Tool execution simulator ready\n"
     ]
    }
   ],
   "source": [
    "def simulate_tool_execution(tool_name: str, arguments: Dict[str, Any]) -> str:\n",
    "    \"\"\"Simulate tool execution (replace with real implementations).\"\"\"\n",
    "    if tool_name == \"get_weather\":\n",
    "        location = arguments.get(\"location\", \"Unknown\")\n",
    "        unit = arguments.get(\"unit\", \"fahrenheit\")\n",
    "        temp = \"72°F\" if unit == \"fahrenheit\" else \"22°C\"\n",
    "        return json.dumps({\n",
    "            \"location\": location,\n",
    "            \"temperature\": temp,\n",
    "            \"condition\": \"Partly cloudy\",\n",
    "            \"humidity\": \"65%\",\n",
    "            \"wind\": \"10 mph NW\"\n",
    "        })\n",
    "    elif tool_name == \"execute_code\":\n",
    "        code = arguments.get(\"code\", \"\")\n",
    "        return json.dumps({\n",
    "            \"status\": \"success\",\n",
    "            \"output\": f\"Code execution simulated for: {code[:50]}...\"\n",
    "        })\n",
    "    elif tool_name == \"web_search\":\n",
    "        query = arguments.get(\"query\", \"\")\n",
    "        return json.dumps({\n",
    "            \"status\": \"success\",\n",
    "            \"results\": [\n",
    "                {\"title\": f\"Result {i+1}\", \"url\": f\"https://example.com/{i+1}\",\n",
    "                 \"snippet\": f\"Information about {query}\"}\n",
    "                for i in range(3)\n",
    "            ]\n",
    "        })\n",
    "    return json.dumps({\"error\": \"Unknown tool\"})\n",
    "\n",
    "print(\"Tool execution simulator ready\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Created MCP agent\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/conversations \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Created session: conv_5613324aa4c3193b1434bf562fe1c75dc2e0563c681738b1\n"
     ]
    }
   ],
   "source": [
    "mcp_agent = Agent(\n",
    "    client=client,\n",
    "    model=\"ollama/llama3.3:70b\",\n",
    "    instructions=\"You are a helpful AI assistant that can answer questions and help with various tasks.\",\n",
    "    tools=mcp_tools # you can set this field to tools when experimenting with the tools created by create_mcp_tools above.\n",
    ")\n",
    "\n",
    "print(\"Created MCP agent\")\n",
    "\n",
    "mcp_session_id = mcp_agent.create_session(session_name=\"mcp_tools_session\")\n",
    "print(f\"✅ Created session: {mcp_session_id}\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: POST http://localhost:8321/v1/responses \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "======================================================================\n",
      "MCP TOOL EXAMPLE\n",
      "======================================================================\n",
      "\n",
      " User: What's the weather like in New York City?\n",
      "\n",
      " Assistant: \n",
      "\n",
      " [Tool Execution Started]\n",
      "\n",
      "\n",
      " [Tool Execution Started]\n",
      "The current weather in New York City is mostly cloudy with a temperature of 49°F and a wind speed of 17 mph NE. Today, it will be partly sunny with a high of 55°F. Tonight, there's a chance of rain showers with a low of 53°F. The rest of the week will see a mix of rain, thunderstorms, and sunshine, with temperatures ranging from the mid-50s to the mid-60s. It's a good idea to check the forecast regularly for updates.The current weather in New York City is mostly cloudy with a temperature of 49°F and a wind speed of 17 mph NE. Today, it will be partly sunny with a high of 55°F. Tonight, there's a chance of rain showers with a low of 53°F. The rest of the week will see a mix of rain, thunderstorms, and sunshine, with temperatures ranging from the mid-50s to the mid-60s. It's a good idea to check the forecast regularly for updates.\n",
      "\n",
      "\n",
      " Summary: Used 2 tool(s) to answer the query\n"
     ]
    }
   ],
   "source": [
    "# Example: Weather query that should trigger tool usage\n",
    "query = \"What's the weather like in New York City?\"\n",
    "\n",
    "print(f\"{'='*70}\")\n",
    "print(f\"MCP TOOL EXAMPLE\")\n",
    "print(f\"{'='*70}\")\n",
    "print(f\"\\n User: {query}\")\n",
    "\n",
    "response = mcp_agent.create_turn(\n",
    "    session_id=mcp_session_id,\n",
    "    messages=[UserMessage(content=query, role=\"user\")],\n",
    "    stream=True,\n",
    ")\n",
    "\n",
    "print(\"\\n Assistant: \", end='')\n",
    "tool_calls_made = []\n",
    "\n",
    "for chunk in response:\n",
    "    event_type = chunk.event.event_type\n",
    "\n",
    "    if event_type == \"step_started\":\n",
    "        if chunk.event.step_type == \"tool_execution\":\n",
    "            print(f\"\\n\\n [Tool Execution Started]\")\n",
    "\n",
    "    elif event_type == \"step_progress\":\n",
    "        # Check for tool call deltas\n",
    "        if hasattr(chunk.event.delta, 'delta_type'):\n",
    "            if chunk.event.delta.delta_type == \"tool_call_issued\":\n",
    "                tool_calls_made.append(chunk.event.delta)\n",
    "                result = simulate_tool_execution(\n",
    "                    chunk.event.delta.tool_name,\n",
    "                    json.loads(chunk.event.delta.arguments)\n",
    "                )\n",
    "        if hasattr(chunk.event.delta, 'text'):\n",
    "            print(chunk.event.delta.text, end='', flush=True)\n",
    "\n",
    "    elif event_type == \"turn_completed\":\n",
    "        output = chunk.event.final_text\n",
    "        if output:\n",
    "            print(output)\n",
    "\n",
    "print()\n",
    "if tool_calls_made:\n",
    "    print(f\"\\n Summary: Used {len(tool_calls_made)} tool(s) to answer the query\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO:httpx:HTTP Request: DELETE http://localhost:8321/v1/conversations/conv_5613324aa4c3193b1434bf562fe1c75dc2e0563c681738b1 \"HTTP/1.1 200 OK\"\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "✅ Session cleaned up\n"
     ]
    }
   ],
   "source": [
    "# Cleanup\n",
    "client.conversations.delete(conversation_id=mcp_session_id)\n",
    "print(\"✅ Session cleaned up\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "---\n",
    "\n",
    "# Summary\n",
    "\n",
    "This notebook demonstrated three levels of Llama Stack agent capabilities:\n",
    "\n",
    "## 1. Basic Agent\n",
    "- ✅ Simple agent creation\n",
    "- ✅ Session management  \n",
    "- ✅ Streaming responses\n",
    "\n",
    "## 2. Advanced Features\n",
    "- ✅ Multi-turn conversations\n",
    "- ✅ RAG (Retrieval-Augmented Generation) pattern\n",
    "- ✅ Custom knowledge base integration\n",
    "\n",
    "## 3. MCP Tools Integration\n",
    "- ✅ MCP-compatible tool definitions\n",
    "- ✅ Automatic tool selection by the agent\n",
    "- ✅ Tool execution and response handling\n",
    "- ✅ Real-time streaming with tool calls\n",
    "\n",
    "\n",
    "## Resources\n",
    "\n",
    "- [Llama Stack Documentation](https://llama-stack.readthedocs.io/)\n",
    "- [Llama Stack GitHub](https://github.com/meta-llama/llama-stack)\n",
    "- [MCP Protocol Specification](https://modelcontextprotocol.io/)\n",
    "- [Ollama Documentation](https://ollama.ai/)"
   ]
  }
 ],
 "metadata": {
  "fileHeader": "",
  "fileUid": "92b7454e-a941-41f0-bd02-6d5e728f20f1",
  "isAdHoc": false,
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.12.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
